/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *
 * @author: jin Chen 
 * @date: Jun 4, 2005$
 * @version: 1.0
 */
package edu.psu.geovista.app.hce.clustering.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class ClusterModel {
    int nbCluster;// 
    int nbLeafCluster;// 

    List <DfLCluster> leafs;  // 
    List clusters;   // 

    BCluster root;

    public ClusterModel() {
        leafs=new ArrayList();
        clusters=new ArrayList();
    }

    public void build(){

        BCluster root = this.getRoot();
        if(root==null){
            throw new UnsupportedOperationException("Found root cluster is null, unable to build");

        }
        else{
            leafs.clear();
            clusters.clear();
            buildCluster(root );
        }
    }

    private  void buildCluster(BCluster cluster){
        // leafs.clear();     
        //    clusters.clear();

        if (!(cluster instanceof LCluster)){//NOT a leaf cluster
            BCluster left = cluster.getCls1(); //
            buildCluster(left);   //always build left first

            cluster.setIndex(nbCluster++);  //count for current cluster
            clusters.add(cluster);
            BCluster right = cluster.getCls2();
            buildCluster(right);  //build right later

        }
        else{//A leaf cluster
            cluster.setIndex(nbCluster++);
            ((LCluster)cluster).setLfindex( nbLeafCluster++);

            leafs.add((DfLCluster) cluster);
            clusters.add(cluster);
        }
    }

    public int getNbCluster() {
        return nbCluster;
    }



    public int getNbLeafCluster() {
        return nbLeafCluster;
    }



    public List getLeafs() {
        Collections.sort(leafs); //force the order of leaf clusters in List match their leafIndex
        return leafs;
    }



    public List getClusters() {
        return clusters;
    }



    public BCluster getRoot() {
        return root;
    }

    public void setRoot(BCluster root) {
        this.root = root;
    }

    public String[] getLeafIds(){
         String[] ids=new String[leafs.size() ];
         int i=0;
         for (Iterator iterator = leafs.iterator(); iterator.hasNext();) {
            LCluster lfc = (LCluster) iterator.next();
             String dataId = lfc.getId();
             ids[i++]=dataId;
         }
        return ids;
    }

    /**
     * Calcualte the max similarity value of the cluster model
     * @return float[0] is the index of the cluster with max sim. float[1] is the max sim value
     */
    public double[] getMaxSimilarity(){
        float maxsim =0;
        int clusterIndex=0;
        for (Iterator iterator = clusters.iterator(); iterator.hasNext();) {
            BCluster binaryCluster = (BCluster) iterator.next();
            float similarity = binaryCluster.getSimilarity();
            if(similarity>maxsim){
                maxsim =similarity;
                clusterIndex=binaryCluster.getIndex();
            }

        }
        return new double[]{clusterIndex, maxsim};
    }

    public double getMinSimilarity(){
        return this.getRoot().getSimilarity() ;
    }
}
